package com.yangyang.ralearn.common.entity.base;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import com.yangyang.ralearn.common.JEnvironment;
import com.yangyang.ralearn.common.types.JType;

/**
 * 谓词定义
 * 
 * @author yautacai
 * 
 */
public class BasePredicateDef implements Comparable<BasePredicateDef> ,Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 2195734105246995408L;
	protected String name;
	public boolean posSensitive = true; // 参数位置是否敏感
	protected List<JType> paramTypes;
	protected JEnvironment environment;

	public BasePredicateDef(JEnvironment environment, String[] array) {
		this.environment = environment;
		if (array == null || array.length == 0) {
			Logger.getLogger(BasePredicateDef.class).error(
					"basepredicatedef constructor error!");
		}
		this.name = array[0];
		this.paramTypes = new ArrayList<JType>();
		for (int i = 1; i < array.length; i++) {
			this.paramTypes.add(environment.mapNameType.get(array[i]));
		}
	}

	public String getName() {
		return this.name;
	}

	public List<JType> getParamTypes() {
		return paramTypes;
	}

	/**
	 * 判断当前的谓词是不是符合所有参数
	 * 
	 * @param mapVar2Type
	 * @return
	 */
	public boolean fit(Map<String, JType> mapVar2Type) {
		Map<JType, Integer> map = new HashMap<JType, Integer>();
		for (Entry<String, JType> entry : mapVar2Type.entrySet()) {
			map.put(entry.getValue(),
					map.containsKey(entry.getValue()) ? map.get(entry
							.getValue()) + 1 : 1);
		}
		for (JType type : this.paramTypes) {
			if (map.containsKey(type) && map.get(type) > 0)
				map.put(type, map.get(type) - 1);
			else
				return false;
		}
		return true;
	}

	@Override
	public int compareTo(BasePredicateDef o) {
		// TODO Auto-generated method stub
		return this.name.compareTo(o.getName());
	}

	@Override
	public String toString() {
		return "BasePredicateDef [type=" + name + ", posSensitive="
				+ posSensitive + ", paramTypes=" + paramTypes + "]";
	}
}
